package com.team3.project.dao.impl;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.team3.project.dao.UserDAO;
import com.team3.project.exception.UserNotFoundException;
import com.team3.project.model.Users;


public class UserDAOImpl implements UserDAO {

	private static final Log log = LogFactory.getLog(UserDAOImpl.class);	
	private static Session session=null;
	private static Transaction tx = null;
	private static Query query =null;
	
	private SessionFactory sessionFactory;

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	private void shutdown() {
		// TODO Auto-generated method stub
		session.close();
	}
	
	public void save(Users user) {
		// TODO Auto-generated method stub

    	try{
    		session = getSessionFactory().openSession();
    		tx = session.beginTransaction();
    		tx.setTimeout(5);
    		
    		session.saveOrUpdate(user);
    	
    		tx.commit();
 
    	}catch(RuntimeException e){
    		try{
    			tx.rollback();
    		}catch(RuntimeException rbe){
    			log.error("Couldn’t roll back transaction", rbe);
    		}
    		throw e;
    	}finally{
    		if(session!=null){
    			shutdown();
    		}
    	}
	}

	public void update(Users users) {
		// TODO Auto-generated method stub
		try{
    		session = getSessionFactory().openSession();
    		tx = session.beginTransaction();
    		tx.setTimeout(5);   		
    		Users u = (Users) session.get(Users.class, users.getId());
    		session.update(u);
    		
    		tx.commit();
 
    	}catch(RuntimeException e){
    		try{
    			tx.rollback();
    		}catch(RuntimeException rbe){
    			log.error("Couldn’t roll back transaction", rbe);
    		}
    		throw e;
    	}finally{
    		if(session!=null){
    			shutdown();
    		}
    	}
	}

	public void delete(Users user) throws UserNotFoundException {
		// TODO Auto-generated method stub
    	try{
    		session = getSessionFactory().openSession();
    		tx = session.beginTransaction();
    		tx.setTimeout(5);
    		
    		Users u = (Users) session.get(Users.class, user.getId());
    		if(u.equals(null))
    		{
    			throw new UserNotFoundException("NOT FOUND USER TO DELETE");
    		}
    		session.delete(u);
    	
    		tx.commit();
 
    	}catch(RuntimeException|UserNotFoundException e){
    		try{
    			tx.rollback();
    		}catch(RuntimeException rbe){
    			log.error("Couldn’t roll back transaction", rbe);
    		}
    		throw e;
    	}
    	finally{
    		if(session!=null){
    			shutdown();
    		}
    	}
	}

	@SuppressWarnings("unchecked")
	public Users findByID(int id) throws UserNotFoundException {
		List<Users> list =null;
	   	try{
    		session = getSessionFactory().openSession();
    		tx = session.beginTransaction();
    		tx.setTimeout(5);
    		
    		query = session.createQuery("from Users where id = :id");
    		query.setParameter("id", id);
    		list = query.list();
    		if(list==null||list.isEmpty())
    		{
    			throw new UserNotFoundException("NOT FOUND USER");		
    		}
    	
    		tx.commit();
 
    	}catch(RuntimeException|UserNotFoundException e){
    		try{
    			tx.rollback();
    		}catch(RuntimeException rbe){
    			log.error("Couldn’t roll back transaction", rbe);
    		}
    		throw e;
    	}finally{
    		if(session!=null){
    			session.close();
    		}
    	}
		return list.get(0);
	}

	@SuppressWarnings("unchecked")
	public List<Users> findAll() {
		List<Users> list;
	   	try{
    		session = getSessionFactory().openSession();
    		tx = session.beginTransaction();
    		tx.setTimeout(5);
  
    		query = session.createQuery("from Users");
    		list =  query.list();
    		
    		tx.commit();
 
    	}catch(RuntimeException e){
    		try{
    			tx.rollback();
    		}catch(RuntimeException rbe){
    			log.error("Couldn’t roll back transaction", rbe);
    		}
    		throw e;
    	}finally{
    		if(session!=null){
    			session.close();
    		}
    	}
		return list;
	}

}
